﻿var SwWebSocket = function (events) {
    var socket = undefined;
    this.Contacts = new Array();
    this.UserInfo = undefined;
    this.OnOpened = events.OnOpened;
    this.OnError = events.OnError;
    this.OnTextMessageReceived = events.OnTextMessageReceived;
    this.OnOwnUserInfoReceived = events.OnOwnUserInfoReceived;
    this.OnNewUserConnected = events.OnNewUserConnected;
    this.OnNewUserOffline = events.OnNewUserOffline;
    this.OrtherMessageReceived = events.OrtherMessageReceived;
    this.OnClosed = events.OnClosed;
    this.SendUserInfoError = events.SendUserInfoError;
    this.SendTextMessageError = events.SendTextMessageError;
    this.SendRequestUsersMessageError = events.SendRequestUsersMessageError;
    this.BroadcastTextMessageReceived = events.BroadcastTextMessageReceived;
    this.UpdateContactsComplete = events.UpdateContactsComplete;

    this.Initialize = function (ip, port) {
        var self = this;
        this.Ip = ip;
        this.Port = port;

        if (typeof WebSocket == "undefined") {
            self.OnError(-1);
            return;
        }

        socket = new WebSocket("ws://" + ip + ":" + port);
        socket.onopen = function (e) {
            self.OnOpened(e);
        }

        socket.onmessage = function (e) {
            var msg = e.data;
            if (typeof e.data == "string") {
                var lengthMsgInfo = Number(msg.substring(0, 128));
                if (!isNaN(lengthMsgInfo)) {
                    var jsonMsgInfo = msg.substring(128, 128 + lengthMsgInfo);
                    var msgInfo = JSON.parse(jsonMsgInfo);
                    var jsonUserInfo;
                    var userInfo;
                    var msgText;
                    switch (msgInfo.MessageType) {
                        case 0://Text
                            msgText = msg.substring(128 + lengthMsgInfo, 128 + lengthMsgInfo + msgInfo.Length);
                            self.OnTextMessageReceived(msgInfo.SendId, msgText);
                            break;
                        case 1://File
                            break;
                        case 2://UserInfo
                            self.OnOwnUserInfoReceived(msgInfo.SendId);
                            break;
                        case 3://Custom
                            break;
                        case 4://Connected
                            jsonUserInfo = msg.substring(128 + lengthMsgInfo, 128 + lengthMsgInfo + msgInfo.Length);
                            userInfo = JSON.parse(jsonUserInfo);
                            if (userInfo.Id !== self.UserInfo.Id) {
                                self.Contacts.push(userInfo);
                                self.OnNewUserConnected(userInfo);
                            }
                            break;
                        case 5://Offline
                            jsonUserInfo = msg.substring(128 + lengthMsgInfo, 128 + lengthMsgInfo + msgInfo.Length);
                            userInfo = JSON.parse(jsonUserInfo);
                            if (userInfo.Id !== self.UserInfo.Id) {
                                if (self.Contacts.length !== 0) {
                                    var index = -1;
                                    for (var i = 0; i < self.Contacts.length; i++) {
                                        if (self.Contacts[i].Id === userInfo.Id) {
                                            index = i;
                                        }
                                    }
                                    if (index !== -1) {
                                        self.Contacts.splice(index, 1);
                                        self.OnNewUserOffline(userInfo);
                                    }
                                }
                            }
                            break;
                        case 6://RequestUsers
                            jsonUserInfo = msg.substring(128 + lengthMsgInfo, 128 + lengthMsgInfo + msgInfo.Length);
                            var users = JSON.parse(jsonUserInfo);
                            self.Contacts = undefined;
                            self.Contacts = users;
                            self.UpdateContactsComplete();
                            break;
                        case 7://RequestSendFile
                            break;
                        case 8://AgreeReceiveFile
                            break;
                        case 9://BroadcastText
                            msgText = msg.substring(128 + lengthMsgInfo, 128 + lengthMsgInfo + msgInfo.Length);
                            self.BroadcastTextMessageReceived(msgInfo.SendId, msgText);
                            break;
                        default:
                            self.OrtherMessageReceived(msg);
                            break;
                    }
                } else {
                    self.OrtherMessageReceived(msg);
                }
            } else {
                self.OrtherMessageReceived(msg);
            }
        }

        socket.onclose = function (e) {
            if (socket != undefined && socket.readyState === WebSocket.OPEN) {
                socket.close();
            }
            self.Contacts = undefined;
            self.Contacts = new Array();
            self.OnClosed(e);
        }

        socket.onerror = function (e) {
            self.OnError(e);
        }
    }

    this.SendUserInfo = function (name, pwd) {
        var self = this;
        if (socket != undefined && socket.readyState === WebSocket.OPEN) {
            self.UserInfo = {
                "Id": Guid.NewGuid().ToString("N").toLocaleUpperCase(),
                "Name": name,
                "Password": pwd,
                "LoginTime": "\/Date(" + Date.now() + ")\/"
            };
            var textJsonUserInfo = JSON.stringify(self.UserInfo);
            var messageInfo = {
                "SendId": self.UserInfo.Id,
                "Length": textJsonUserInfo.length,
                "MessageType": 2
            }
            var textJsonMsgInfo = JSON.stringify(messageInfo);
            var length = String(textJsonMsgInfo.length);
            var arrlength = StringTo128Length(length);
            socket.send(arrlength + textJsonMsgInfo + textJsonUserInfo);
        } else {
            self.SendUserInfoError();
        }
    }

    this.SendTextMessage = function (id, value) {
        if (value === "")
            return;
        var self = this;
        if (socket != undefined && socket.readyState === WebSocket.OPEN) {
            var messageInfo = {
                "SendId": self.UserInfo.Id,
                "ReceiveId": id,
                "Length": value.length,
                "MessageType": 0
            }
            var textJsonMsgInfo = JSON.stringify(messageInfo);
            var length = String(textJsonMsgInfo.length);
            var arrlength = StringTo128Length(length);
            socket.send(arrlength + textJsonMsgInfo + value);
        } else {
            self.SendTextMessageError();
        }
    }

    this.GetUserById = function (id) {
        var self = this;
        var user = undefined;
        for (var i = 0; i < self.Contacts.length; i++) {
            if (self.Contacts[i].Id === id) {
                user = self.Contacts[i];
                break;
            }
        }
        return user;
    }

    this.Stop = function () {
        if (socket != undefined && socket.readyState === WebSocket.OPEN) {
            socket.close();
        }
    }

    this.SendRequestUsersMessage = function () {
        var self = this;
        if (socket != undefined && socket.readyState === WebSocket.OPEN) {
            var msgInfo = {
                "MessageType": 6
            };
            var jsonMsgInfo = JSON.stringify(msgInfo);
            var length = String(jsonMsgInfo.length);
            var arrlength = StringTo128Length(length);
            socket.send(arrlength + jsonMsgInfo);
        } else {
            self.SendRequestUsersMessageError();
        }
    }

    this.BroadcastTextMessage = function (value) {
        if (value === "")
            return;
        var self = this;
        if (socket != undefined && socket.readyState === WebSocket.OPEN) {
            var messageInfo = {
                "SendId": self.UserInfo.Id,
                "ReceiveId": null,
                "Length": value.length,
                "MessageType": 9
            }
            var textJsonMsgInfo = JSON.stringify(messageInfo);
            var length = String(textJsonMsgInfo.length);
            var arrlength = StringTo128Length(length);
            socket.send(arrlength + textJsonMsgInfo + value);
        } else {
            self.SendTextMessageError();
        }
    }
}

function StringTo128Length(value) {
    var length = 128 - value.length;
    var result = value;
    if (length > 0) {
        for (var i = 0; i < length; i++) {
            result = "0" + result;
        }
    }
    return result;
}

function Guid(value) {
    var array = new Array();
    if (typeof value == "string") {
        initializeByString(array, value);
    } else {
        initializeByOther(array);
    }

    this.IsGuid = function () { }

    this.ToString = function (format) {
        if (typeof format == "string") {
            if (format === "N" || format === "D" || format === "B" || format === "P") {
                return toStringWithFormat(array, format);
            } else {
                return toStringWithFormat(array, "D");
            }
        } else {
            return toStringWithFormat(array, "D");
        }
    }

    function initializeByString(a, g) {
        g = g.replace(/\{|\(|\)|\}|-/g, "");
        g = g.toLowerCase();
        if (g.length !== 32 || g.search(/[^0-9,a-f]/i) !== -1) {
            initializeByOther(a);
        }
        else {
            for (var i = 0; i < g.length; i++) {
                a.push(g[i]);
            }
        }
    }

    function initializeByOther(a) {
        var i = 32;
        while (i--) {
            a.push("0");
        }
    }

    function toStringWithFormat(a, format) {
        var str;
        switch (format) {
            case "N":
                return a.toString().replace(/,/g, "");
            case "D":
                str = a.slice(0, 8) + "-" + a.slice(8, 12) + "-" + a.slice(12, 16) + "-" + a.slice(16, 20) + "-" + a.slice(20, 32);
                str = str.replace(/,/g, "");
                return str;
            case "B":
                str = toStringWithFormat(a, "D");
                str = "{" + str + "}";
                return str;
            case "P":
                str = toStringWithFormat(a, "D");
                str = "(" + str + ")";
                return str;
            default:
                return new Guid();
        }
    }
}

Guid.Empty = new Guid();

Guid.NewGuid = function () {
    var g = "";
    var i = 32;
    while (i--) {
        g += Math.floor(Math.random() * 16.0).toString(16);
    }
    return new Guid(g);
}

function IsIp(ip) {
    var re =
        /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
    return re.test(ip);
}

function getFmtDateTime(date) {
    if (!date) {
        date = new Date();
    }
    var seperator1 = "-";
    var seperator2 = ":";
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
            + " " + date.getHours() + seperator2 + date.getMinutes()
            + seperator2 + date.getSeconds();
    return currentdate;
}

function GetRandomName() {
    var firstName = "赵,钱,孙,李,周,吴,郑,王,冯,陈,褚,卫,蒋,沈,韩,杨,朱,秦,尤,许,何,吕,施,张,孔,曹,严,华,金,魏,陶,姜, 戚,谢,邹,喻,柏,水,窦,章,云,苏,潘,葛,奚,范,彭,郎,鲁,韦,昌,马,苗,凤,花,方,俞,任,袁,柳,丰,鲍,史,唐, 费,廉,岑,薛,雷,贺,倪,汤,滕,殷,罗,毕,郝,邬,安,常,乐,于,时,傅,皮,卞,齐,康,伍,余,元,卜,顾,孟,平,黄, 和,穆,萧,尹,姚,邵,湛,汪,祁,毛,禹,狄,米,贝,明,臧,计,伏,成,戴,谈,宋,茅,庞,熊,纪,舒,屈,项,祝,董,梁, 杜,阮,蓝,闵,席,季,麻,强,贾,路,娄,危,江,童,颜,郭,梅,盛,林,刁,钟,徐,丘,骆,高,夏,蔡,田,樊,胡,凌,霍, 虞,万,支,柯,昝,管,卢,莫,经,房,裘,缪,干,解,应,宗,丁,宣,贲,邓,郁,单,杭,洪,包,诸,左,石,崔,吉,钮,龚, 程,嵇,邢,滑,裴,陆,荣,翁,荀,羊,於,惠,甄,麴,家,封,芮,羿,储,靳,汲,邴,糜,松,井,段,富,巫,乌,焦,巴,弓, 牧,隗,山,谷,车,侯,宓,蓬,全,郗,班,仰,秋,仲,伊,宫,宁,仇,栾,暴,甘,钭,厉,戌,祖,武,符,刘,景,詹,束,龙, 叶,幸,司,韶,郜,黎,蓟,薄,印,宿,白,怀,蒲,邰,从,鄂,索,咸,籍,赖,卓,蔺,屠,蒙,池,乔,阴,郁,胥,能,苍,双, 闻,莘,党,翟,谭,贡,劳,逢,姬,申,扶,堵,冉,宰,郦,雍,郤,璩,桑,桂,濮,牛,寿,通,边,扈,燕,冀,郏,浦,尚,农, 温,别,庄,晏,柴,瞿,阎,充,慕,连,茹,习,宦,艾,鱼,容,向,古,易,慎,戈,廖,庾,终,暨,居,衡,步,都,耿,满,弘, 匡,国,文,寇,广,禄,阙,东,欧,殳,沃,利,蔚,越,菱,隆,师,巩,厍,聂,晃,勾,敖,融,冷,訾,辛,阚,那,简,饶,空, 曾,毋,沙,乜,养,鞠,须,丰,巢,关,蒯,相,查,后,荆,红,游,竺,权,逯,盖,益,桓,公,万俟,司马,上官,欧阳,夏侯,诸葛,闻人,东方,赫连,皇甫,尉迟,公羊,澹台,公冶,宗政,濮阳,淳于,单于,太叔,申屠,公孙,仲孙,轩辕,令狐,钟离,宇文,长孙,慕容,司徒,司空";
    var lastName = "努,迪,立,林,维,吐,丽,新,涛,米,亚,克,湘,明,白,玉,代,孜,霖,霞,加,永,卿,约,小,刚,光,峰,春,基,木,国,娜,晓,兰,阿,伟,英,元,音,拉,亮,玲,木,兴,成,尔,远,东,华,旭,迪,吉,高,翠,莉,云,华,军,荣,柱,科,生,昊,耀,汤,胜,坚,仁,学,荣,延,成,庆,音,初,杰,宪,雄,久,培,祥,胜,梅,顺,涛,西,库,康,温,校,信,志,图,艾,赛,潘,多,振,伟,继,福,柯,雷,田,也,勇,乾,其,买,姚,杜,关,陈,静,宁,春,马,德,水,梦,晶,精,瑶,朗,语,日,月,星,河,飘,渺,星,空,如,萍,棕,影,南,北";
    var nameLength = Math.round(Math.random() * (4 - 2) + 2);
    var firstNames = firstName.split(",");
    var lastNames = lastName.split(",");
    var name = undefined;
    if (nameLength === 2) {
        name = firstNames[Math.floor(Math.random() * firstNames.length)] +
            lastNames[Math.floor(Math.random() * lastNames.length)];
    } else {
        name = firstNames[Math.floor(Math.random() * firstNames.length)] +
            lastNames[Math.floor(Math.random() * lastNames.length)] +
            lastNames[Math.floor(Math.random() * lastNames.length)];
    }
    return name;
}